require 'optparse'

class Array
  def groups(&block)
    index = 0
    step = block.arity
    if step <= 0 then return end
    while index + step <= size
      args = []
      for i in 0 ... step
        args << self[index]
        index += 1
      end
      block.call(*args)
    end
  end
end

class ArgumentsParser
  def self.parse(args)
    parser = OptionParser.new
    parser.program_name = "driver"
    parser.version = "0.1"

    options = {}
    parser.on("-l", "--[no-]learn", "Online-Learn enabled") do |v|
      options[:learn_enabled] = v
    end

    parser.on("-m", "--[no-]mail", "E-mail enabled") do |v|
      options[:mail_enabled] = v
    end

    parser.on("-oFILE", "Output data file") do |v|
      options[:data_file_name] = v
    end
    
    parser.on("-h", "-?", "--help", "--usage", "--about", "Print this help") do
      puts parser
    end
      
    parser.on("-i", "--login USERNAME,PASSWORD", Array, "Username and password for Online-learn") do |v|
      if v.size >= 1
      options[:learn_username] = v[0]
        if v.size >= 2
          options[:learn_password] = v[1]
        end
      end
    end

    parser.on("-b", "--mailboxes USERNAME1,PASSWORD1,TYPE1,USERNAME2,PASSWORD2,TYPE2,...", Array, "Username, password and type(yahoo, gmail or tsinghua) for each mailbox") do |v|
      options[:mailboxes] = []
      v.groups do |a, b, c|
        mailbox = {}
        mailbox[:type] = a
        mailbox[:username] = b
        mailbox[:password] = c
        options[:mailboxes] << mailbox
      end
    end
    
    parser.on_tail() do
      if options[:mail_enabled] and (options[:mailboxes].nil? or options[:mailboxes].empty?)
        raise "Since E-mail function is enabled, at least one mailbox should be given"
      end
      if options[:learn_enabled] and ! options[:learn_username]
        raise "Since Online-Learn function is enabled, the login username should be given"
      end
      if options[:learn_enabled] and ! options[:learn_password]
        raise "Since Online-Learn function is enabled, the login password should be given"
      end
      if (options[:learn_enabled] or options[:mail_enabled]) and ! options[:data_file_name]
        raise "Ouput data file name should be given"
      end
      
    end
    
    parser.on("-p", "--plain", "Output with plain-text format") do |v|
      options[:plain_text] = v
    end
    
    parser.on("-d", "--dummy", "Use dummy scraper (for debug)") do |v|
      options[:use_dummy] = v
    end

    #~ args = %w{-l -m -i learn_username,learn_password -b yahoo,yahoo_username,yahoo_password,gmail,gmail_username,gmail_password,tsinghua,tsinghua_username,tsinghua_password -d -odata.xml}
    begin
      parser.parse args
    rescue Exception => e
      STDERR.puts "Error: " + e.message
      STDERR.puts parser
      return nil
    end
    
    if args.empty?
      STDERR.puts parser
    end
  
    log(options)
    
    options
  end
  
  def self.log(options)
    File.open('arguments_log.txt', 'a') do |f|
      f.puts Time.now.to_s + "==================================="
      f.puts options.inspect
    end
  end
  
end